package com.small.sentinel.slots.block.authority;

import com.small.common.core.spi.Spi;
import com.small.common.designPattern.behavioral.chainOfResponsibility.slotchain.AbstractLinkedProcessorSlot;
import com.small.sentinel.Constants;
import com.small.sentinel.Context;
import com.small.sentinel.slotchain.ResourceWrapper;
import com.small.sentinel.slots.SentinelResource;

import java.util.Map;
import java.util.Set;

@Spi(order = Constants.ORDER_AUTHORITY_SLOT)
public class AuthoritySlot extends AbstractLinkedProcessorSlot<SentinelResource> {

    @Override
    public void entry(SentinelResource resource) throws Throwable {
        checkBlackWhiteAuthority(resource);
        fireEntry(resource);
    }

    @Override
    public void exit(SentinelResource resource) throws Throwable {
        fireExit(resource);
    }

    /**
     * 校验黑白名单
     *
     * @param resource
     */
    private void checkBlackWhiteAuthority(SentinelResource resource) throws AuthorityException {

        ResourceWrapper resourceWrapper = resource.getResourceWrapper();
        Context context = resource.getContext();

        //获取所有权限校验规则
        Map<String, Set<AuthorityRule>> authorityRules = AuthorityRuleManager.getAuthorityRules();
        if (authorityRules == null) {
            return;
        }
        Set<AuthorityRule> rules = authorityRules.get(resourceWrapper.getName());
        if (rules == null) {
            return;
        }
        for (AuthorityRule rule : rules) {
            if (!AuthorityRuleChecker.passCheck(rule, context)) {
                throw new AuthorityException(context.getOrigin(), rule);
            }
        }
    }
}
